package mspbots.teams.common;

import org.springframework.util.LinkedMultiValueMap;

import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * mspbots.smileback.QueryParams
 *
 * @author <a href="https://github.com/vnobo">Alex bob</a>
 * @date Created by 2020/10/26
 */
public class QueryParams extends LinkedMultiValueMap<String, String> {

    /**
     * Retrieves the total count of matching resources.
     * /me/messages?$top=2&$count=true
     */
    private boolean count;
    /**
     * Retrieves related resources.
     * /groups?$expand=members
     */
    private String expand;
    /**
     * Filters results (rows).
     * /users?$filter=startswith(givenName,'J')
     */
    private String filter;
    /**
     * Returns the results in the specified media format.
     * /users?$format=json
     */
    private String format;
    /**
     * Orders results.
     * /users?$orderby=displayName desc
     */
    private String orderBy;
    /**
     * Returns results based on search criteria.
     * /me/messages?$search=pizza
     */
    private String search;
    /**
     * Filters properties (columns).
     * /users?$select=givenName,surname
     */
    private String select;

    /**
     * Sets the page size of results.
     * /users?$top=2
     */
    private int top;
    /**
     * Indexes into a result set. Also used by some APIs to implement paging and can be used
     * together with $top to manually page results.
     * /me/messages?$skip=11
     */
    private int skip;

    private String nextLink;

    public QueryParams() {
        super(new LinkedHashMap<>());
        this.top = 50;
        this.put("$top", List.of(String.valueOf(this.top)));
    }

    /**
     * Create a new LinkedMultiValueMap that wraps a {@link LinkedHashMap}
     * with the given initial capacity.
     *
     * @param initialCapacity the initial capacity
     */
    public QueryParams(int initialCapacity) {
        super(new LinkedHashMap<>(initialCapacity));
    }

    /**
     * Copy constructor: Create a new LinkedMultiValueMap with the same mappings as
     * the specified Map. Note that this will be a shallow copy; its value-holding
     * List entries will get reused and therefore cannot get modified independently.
     *
     * @param otherMap the Map whose mappings are to be placed in this Map
     * @see #clone()
     * @see #deepCopy()
     */
    public QueryParams(Map<String, List<String>> otherMap) {
        super(new LinkedHashMap<>(otherMap));
    }

    /**
     * default query params
     * max records 500
     * page 0
     *
     * @return default query body
     */
    public static QueryParams withDefault() {
        return new QueryParams(8);
    }


    public QueryParams setTop(Integer top) {
        this.put("$top", List.of(top.toString()));
        this.top = top;
        return this;
    }

    public QueryParams setFilter(String filter) {
        this.put("$filter", List.of(filter));
        this.filter = filter;
        return this;
    }

    public QueryParams setSelect(String select) {
        this.put("$select", List.of(select));
        this.select = select;
        return this;
    }

    public QueryParams setExpand(String expand) {
        this.put("$expand", List.of(expand));
        this.expand = expand;
        return this;
    }

}
